/**
 * Created by zaranengap on 2017/7/4.
 * refactoring by zhouli on 2019/3/15
 * 主要是权限控制重构：去掉account里面的角色控制，FP控制菜单，采用后端动态权限字段与后端计算后的菜单
 * 一旦切换集团|公司|管理员|员工模式就重新请求菜单
 */
import React from "react";
import ReactDOM from "react-dom";
import { connect } from "react-redux";
import {
  Layout,
  Menu,
  Breadcrumb,
  Icon,
  Tooltip,
  Divider,
  Popover,
  message,
} from "antd";
import { Link } from "react-router";
import "styles/main.scss";
import menuRoute from "routes/menuRoute";
import {
  setTenantMode,
  setAdminMode,
  setSelectedMenu,
  setPublicToken,
} from "actions/main";
import { setAllCurrency } from "actions/cache";
import Loading from "components/loading";
import Error from "components/error";
import SVGIcon from "components/SVGIcon";
import GlobalSearch from "containers/components/global-search";
import CommonFunc from "containers/components/common-function";
import { deepFullCopy, messages, removeArryItem, sortMenu } from "share/common";
import baseService from "share/base.service";
import StopAnnonuce from "components/template/stop-annonuce/stop-annonuce";
import CustomLogo from "containers/components/custom-logo";
import UserInfo from "containers/components/user-info";
import CustomerFeedBackOnlineService from "containers/components/customer-and-feedback-online-service";
import TryRegister from "containers/components/try-register";
import ModeMenu from "containers/components/mode-menu";
import configureStore from "stores";
import routeService from "routes/route.service";
import TryloginService from "containers/login/components/try-login/try-login.service";
import closeGuide from "components/method/closeGuide";
import menuControl from "components/method/menuControl";
import NewProtocolModal from "components/template/new-user-protocol/new-user-protocol";
import WelcomeMessagesModal from "components/template/welcome-messages-modal/welcome-messages-modal";
import OperatingInstuction from "containers/operating-instruction/operating-instruction";
import mainService from "containers/main.service";
import ListSelector from "components/list-selector";
import errorMessage from "share/errorMessage";
import RequireETraining from "components/require-etraining";
import UpdateNotice from "components/update-notice";

const { SubMenu } = Menu;
const { Header, Content, Sider } = Layout;
let cacheUrl = localStorage.getItem("hly.cacheUrl")
  ? JSON.parse(localStorage.getItem("hly.cacheUrl"))
  : [];

/**
 * 2018/11/26 ZaraNengap
 * 整个应用外层的壳子
 * 本来想做成一个项目基本布局和权限控制的中心
 * 但是现在加了越来越多不属于我原本目的的东西
 * 如果有时间，请后来者不要在这里再增加其他东西了，很多东西不属于这里
 * 截止现在，这个文件1247行
 * 截止现在，这个文件 850 行
 * 截止现在，这个文件 579 行
 * 对应的开发，再把我标记的几个todo 干掉，这个文件就清爽了
 */
class Main extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      // 兼容老权限，还有一个租户
      // 现在没有了
      menu: props.newPermissionSortedMenus,
      userPermissionAllMenus: props.userPermissionAllMenus,
      collapsed: false,
      selectedKeys: [],
      openKeys: [],
      check: false,
      error: false,
      errorContent: {},
      routeIsShow: {
        "sub-application-view": true,
        "mileage-subsidy-expense": true,
      },
      operatingVisible: false,
      currentCode: props.language.code,
      hasRouteParam: null,
      menuConfig:
        JSON.parse(
          localStorage.getItem(
            `hly.menuConfig.${props.tenantMode ? "tenantMode" : "companyMode"}`
          )
        ) || {},
      oldState: null,
      spinning: false,
    };
    this.isInMenu = true;
    this.isInSubMenu = false;
    this.keyArr = [];
  }

  componentWillMount() {
    window.scrollTo(0, 0);
    menuRoute.updateCurrentPageFun();
  }

  componentDidMount() {
    const { user, currentPage } = this.props;
    baseService.getProfile();
    this.getCurrencyList();
    this.checkRoute();
    this.getPublicToken(); // 获取公版access_token by ting.zhang
    // mainService.getAvailableCompany();
    this.isShowTrailTip();
    // 检测页面权限
    mainService.checkParams(this);
    // mainService.checkScanSnap(this.props.dispatch);
    // 激活菜单
    this.setMenuSelectedState();
    if (user.enableNewPermission) {
      const key = currentPage[0].subMenu
        ? currentPage[1].key
        : currentPage[0].key;
      this.setState({
        selectedKeys: [key],
      });
    }
  }

  componentWillUnmount() {
    closeGuide();
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.location.state !== nextProps.location.state) {
      this.setState({
        oldState: this.props.location.state,
      });
    }
    // key变化即表示换页面了
    if (this.props.location.key !== nextProps.location.key) {
      closeGuide();
      mainService.checkParams(this);
      window.scrollTo(0, 0);
    } else {
      if (nextProps.currentPage && nextProps.currentPage.length > 1) {
        const needCacheKeys = ["approve-request-quick-view"];
        const currentPageInfo =
          nextProps.currentPage[nextProps.currentPage.length - 1];
        if (~needCacheKeys.indexOf(currentPageInfo.key)) {
          const urlInfo = {
            key: currentPageInfo.key,
            url: this.props.location.pathname + this.props.location.search,
          };
          removeArryItem(
            cacheUrl,
            cacheUrl.filter((item) => item.key === currentPageInfo.key)[0]
          );
          cacheUrl.push(urlInfo);
        }
      } else {
        cacheUrl = [];
      }
      localStorage.setItem("hly.cacheUrl", JSON.stringify(cacheUrl));
      this.setState(
        {
          openKeys: this.state.collapsed ? [] : [nextProps.currentPage[0].key],
        },
        () => {
          nextProps.currentPage[0].subMenu
            ? this.setState({ selectedKeys: [nextProps.currentPage[1].key] })
            : this.setState({ selectedKeys: [nextProps.currentPage[0].key] });
        }
      );
    }
  }

  onCollapse = (collapsed) => {
    this.setState({ collapsed });
    if (collapsed) {
      const subMenu = document.querySelectorAll(".ant-menu-submenu");
      subMenu.forEach((item) => (item.style.left = "84px"));
    } else {
      const openMenuItem = menuRoute.getMenuItemByAttr(
        this.state.selectedKeys[0],
        "key"
      );
      this.setState({
        openKeys: openMenuItem.parent ? [openMenuItem.parent] : [],
      });
    }
  };

  // 是否显示试用提醒
  isShowTrailTip = () => {
    const { user } = this.props;
    const isShowTrailTip = window.sessionStorage.getItem("isShowTrailTip");
    // 必须是试用，且没有展示过试用提示
    if (user.tenantType === "FREE_TRIAL" && !isShowTrailTip) {
      TryloginService.freeTrailInfo();
    }
  };

  getCurrencyList = () => {
    baseService.getCurrencyList("", "").then((res) => {
      configureStore.store.dispatch(setAllCurrency(res.data.rows));
    });
  };

  checkRoute = () => {
    routeService.getRouteIsShow().then((routeIsShow) => {
      this.setState({ routeIsShow });
    });
  };

  setMenuSelectedState = (targetMenu) => {
    const nowMenuItem =
      targetMenu ||
      menuRoute.getMenuItemByAttr(
        this.props.routes[this.props.routes.length - 1].path,
        "url"
      );
    this.setState({
      selectedKeys: [nowMenuItem.key],
      openKeys: nowMenuItem.parent ? [nowMenuItem.parent] : [],
    });
  };

  /**
   * 切换模式
   * @param adminMode  切换到管理员模式
   * @param tenantMode 切换到集团模式
   * @param targetMenu 切换模式后的目标菜单 默认为设置的主页
   * */
  handleModeChangeV2 = (adminMode, tenantMode, targetMenu) => {
    this.setState({ spinning: true });
    let modeChangeTimer = null;
    adminMode !== null && this.props.dispatch(setAdminMode(adminMode));
    tenantMode !== null && this.props.dispatch(setTenantMode(tenantMode));
    tenantMode !== null && this.setMenuConfig(tenantMode);
    if (modeChangeTimer) {
      clearTimeout(modeChangeTimer);
    }
    // 为了保证先切换模式再执行菜单跳转
    modeChangeTimer = setTimeout(() => {
      const { tenantMode, adminMode, user, isOldCompany } = this.props;
      const { menu } = this.state;
      let indexMenu = null; // 主页菜单
      if (user.enableNewPermission) {
        const checkMenuAuthParams = [adminMode, tenantMode, isOldCompany];
        const firstPath = mainService.lookForFirstMenu(
          menu,
          ...checkMenuAuthParams
        );
        if (firstPath && firstPath.url) {
          indexMenu = firstPath;
        } else {
          this.setState({
            check: true,
            error: true,
            errorContent: {
              title: messages("dashboard.key89" /* 出错啦 */),
              text: messages(
                "dashboard.key191"
              ) /* 当前模式下无可查看页面，如有疑问请联系系统管理员 */,
              buttonText: "",
              hasButton: false,
            },
          });
        }
      } else {
        indexMenu = menuRoute.indexUrl;
        adminMode && tenantMode && (indexMenu = menuRoute.adminTenantIndexUrl);
        adminMode &&
          !tenantMode &&
          (indexMenu = menuRoute.adminCompanyIndexUrl);
      }
      indexMenu = targetMenu || indexMenu;
      indexMenu && this.setMenuSelectedState(indexMenu);
      indexMenu && this.menuRouterDeal(indexMenu);
      this.setState({ spinning: false });
    });
  };

  // 切换公司
  handleChangeCompany = (companyId) => {
    this.setState({ spinning: true });
    mainService
      .changeCompany(companyId)
      .then(() =>
        baseService.getInfo().then(() => {
          this.setState({ spinning: false });
          this.handleModeChangeV2(null, false);
        })
      )
      .catch((err) => {
        errorMessage(err || message("common.error1"));
        this.setState({ spinning: false });
      });
  };

  // 获取菜单排序缓存
  setMenuConfig = (isTenant) => {
    this.setState({
      menuConfig:
        localStorage.getItem(
          `hly.menuConfig.${isTenant ? "tenantMode" : "companyMode"}`
        ) || {},
    });
  };

  // 优化collapsed菜单交互
  handleMenuEnter = (e) => {
    this.keyArr.push(e.key);
    const self = this;
    const id = setTimeout(() => {
      clearTimeout(id);
      if (self.hasLeavedSubMenu)
        self.setState({ openKeys: [self.keyArr.pop()] });
      if (!self.isInSubMenu && !self.hasLeavedSubMenu)
        self.setState({ openKeys: [e.key] });
      self.hasLeavedSubMenu = false;
      self.keyArr = [];
    }, 200);
  };

  handleSubMenuEnter = (e) => {
    const subMenu = ReactDOM.findDOMNode(e.domEvent.target).parentNode
      .parentNode;
    subMenu.addEventListener("mouseenter", () => {
      this.isInSubMenu = true;
    });
  };

  handleSubMenuLeave = (e) => {
    const subMenu = ReactDOM.findDOMNode(e.domEvent.target).parentNode
      .parentNode;
    subMenu.addEventListener("mouseleave", () => {
      this.isInSubMenu = false;
      this.hasLeavedSubMenu = true;
      const self = this;
      const id = setTimeout(() => {
        clearTimeout(id);
        !self.isInMenu && self.setState({ openKeys: [] });
      }, 100);
    });
  };

  hideSubMenu = () => {
    const self = this;
    const id = setTimeout(() => {
      clearTimeout(id);
      self.setState({ openKeys: [] });
    }, 200);
  };

  /**
   * 获取公版access_token by ting.zhang
   */
  getPublicToken() {
    baseService
      .getThirdPartyToken()
      .then((res) => {
        const { data } = res;
        const token = data.access_token;
        // sessionStorage.setItem('public.token', token);
        configureStore.store.dispatch(setPublicToken(token));
      })
      .catch((e) => {});
  }

  handleMenuClick = (e) => {
    if (e.key === this.state.openKeys[0]) {
      this.setState({ openKeys: [] });
    } else {
      this.setState({ openKeys: [e.key] });
    }
  };

  // 路由跳转
  menuRouterDeal = (item) => {
    routeService.menuRouterDeal(item, this.context, this.props.authToken);
  };

  renderMenu() {
    const { selectedKeys, openKeys, menu, menuConfig, collapsed } = this.state;
    const { tenantMode, isOldCompany, adminMode } = this.props;
    const checkMenuAuthParams = [adminMode, tenantMode, isOldCompany];

    return (
      <Menu
        theme="dark"
        mode="inline"
        style={{ width: collapsed ? 80 : 206 }}
        selectedKeys={selectedKeys}
        inlineCollapsed={collapsed}
        openKeys={openKeys}
        onSelect={(e) => {
          this.setState({ selectedKeys: [e.key] });
        }}
      >
        {sortMenu(menu, Object.keys(menuConfig)).map((item) => {
          const hasPermission = mainService.checkMenuAuth(
            item,
            ...checkMenuAuthParams
          );

          if (item.subMenu) {
            if (hasPermission) {
              return (
                <SubMenu
                  key={item.key}
                  className={collapsed ? "collapsed-menu" : ""}
                  onMouseEnter={collapsed ? this.handleMenuEnter : () => {}}
                  onTitleClick={this.handleMenuClick}
                  title={
                    <span  data-resource-order={item.resourceOrder}>
                      <Icon type={item.ficon ? item.ficon : item.icon} />
                      <span className="nav-text" data-resource-order={item.resourceOrder}>
                        {item.menuName
                          ? item.menuName
                          : messages(`menu.${item.key}`)}
                      </span>
                    </span>
                  }
                >
                  {sortMenu(item.subMenu, menuConfig[item.key]).map((subItem) =>
                    mainService.checkMenuAuth(
                      subItem,
                      ...checkMenuAuthParams
                    ) ? (
                      <Menu.Item
                        key={subItem.key}
                        onMouseEnter={
                          collapsed ? this.handleSubMenuEnter : () => {}
                        }
                        onMouseLeave={
                          collapsed ? this.handleSubMenuLeave : () => {}
                        }
                      >
                        <div onClick={() => this.menuRouterDeal(subItem)} data-resource-order={subItem.resourceOrder}>
                          {subItem.menuName
                            ? subItem.menuName
                            : messages(`menu.${subItem.key}`)}

                        </div>
                      </Menu.Item>
                    ) : null
                  )}
                </SubMenu>
              );
            }
            return null;
          }

          if (hasPermission) {
            return (
              <Menu.Item
                key={item.key}
                onMouseEnter={collapsed ? this.hideSubMenu : () => {}}
              >
                <div onClick={() => this.menuRouterDeal(item)} data-resource-order={item.resourceOrder}>
                  <span>
                    <Icon type={item.ficon ? item.ficon : item.icon} />
                    <span className="nav-text" data-resource-order={item.resourceOrder}>
                      {item.menuName
                        ? item.menuName
                        : messages(`menu.${item.key}`)}
                    </span>
                  </span>
                </div>
              </Menu.Item>
            );
          }

          return null;
        })}
      </Menu>
    );
  }

  // 渲染面板屑导航
  // todo
  // move main/components/
  renderBreadcrumb() {
    const { oldState } = this.state;
    const { currentPage, location } = this.props;
    return (
      <Breadcrumb className="breadcrumb" separator={<Icon type="right" />}>
        {currentPage.map((item, i) => {
          const classNameStr =
            i === currentPage.length - 1 ? "last-breadcrumb" : null;
          if (item.url && i !== currentPage.length - 1) {
            return (
              <Breadcrumb.Item key={item.key}>
                <Link
                  to={mainService.transRealUrl(
                    item,
                    cacheUrl,
                    location,
                    currentPage
                  )}
                  state={oldState}
                >
                  {item.menuName ? item.menuName : messages(`menu.${item.key}`)}
                </Link>
              </Breadcrumb.Item>
            );
          }
          return (
            <Breadcrumb.Item key={item.key} className={classNameStr}>
              {item.menuName ? item.menuName : messages(`menu.${item.key}`)}
            </Breadcrumb.Item>
          );
        })}
      </Breadcrumb>
    );
  }

  // Route的渲染写在render外面，避免You cannot change <Router routes>; it will be ignored警告
  mainRoute = menuRoute.getMainRoute();

  closeOperatingInstuction = () => {
    this.setState({ operatingVisible: false });
  };

  // 渲染 管理员模式 | 员工模式
  renderModeBtn = () => {
    const { userPermission, adminMode, user } = this.props;
    const dom = (
      <div
        className="admin-button"
        onClick={() => this.handleModeChangeV2(!adminMode, null)}
      >
        <Icon
          type="login"
          style={
            adminMode
              ? {
                  transform: "rotateY(180deg)",
                  WebkitTransform: "rotateY(180deg)",
                  MsTransform: "rotateY(180deg)",
                  MozTransform: "rotateY(180deg)",
                }
              : {}
          }
        />
        {!user.mock && adminMode && (
          <span className="title">
            {messages("dashboard.key189") /* 回到员工模式 */}
          </span>
        )}
        {!adminMode && (
          <span className="title">
            {messages("dashboard.key190") /* 进入管理后台 */}
          </span>
        )}
      </div>
    );
    /*
     * 启用新权限控制
     * 只要有集团管理员或者公司管理员权限之一，就需要显示模式切换
     * */
    if (
      user.enableNewPermission &&
      (userPermission.hasTenantRole || userPermission.adminMode)
    ) {
      return dom;
    }
    // 没有启用新权限控制
    if (
      !user.enableNewPermission &&
      this.hasAnyAuthorities(["ROLE_TENANT_ADMIN", "ROLE_COMPANY_ADMIN"])
    ) {
      return dom;
    }
    return null;
  };

  render() {
    const {
      check,
      error,
      errorContent,
      operatingVisible,
      collapsed,
      spinning,
    } = this.state;
    const { tenantMode, isOldCompany, language, loginUser, adminMode, user } =
      this.props;

    return (
      <RequireETraining>
        <div className="helios-main">
          <UpdateNotice />
          <Sider
            width={collapsed ? 80 : 206}
            className="helios-sider"
            collapsible
            collapsed={collapsed}
            trigger={null}
          >
            <ModeMenu
              onCollapse={this.onCollapse}
              onChangeCompany={this.handleChangeCompany}
              onChangeMode={this.handleModeChangeV2}
              spinning={spinning}
            />
            <div
              className="menu-container"
              style={{
                height:
                  user.tenantType === "FREE_TRIAL"
                    ? "calc(100% - 80px)"
                    : "calc(100% - 64px)",
              }}
              onMouseEnter={() => {
                this.isInMenu = true;
              }}
              onMouseLeave={() => {
                this.isInMenu = false;
              }}
            >
              {this.renderMenu()}
            </div>
            {/* 试用账号显示注册入口 */}
            {user.tenantType === "FREE_TRIAL" && <TryRegister />}
            {/* 在线客服与反馈 */}
            {/* <CustomerFeedBackOnlineService collapsed={collapsed}/> */}
          </Sider>
          <div
            style={{
              marginLeft: collapsed ? 80 : 206,
              width: `calc(100% - ${collapsed ? "80px" : "206px"})`,
            }}
            className="content-layout"
          >
            <Header
              className="helios-header"
              style={{ width: `calc(100% - ${collapsed ? "80px" : "206px"})` }}
            >
              {CustomLogo(this.props.tenant)}
              <div className="user-area">
                {/* 全局搜索等菜单和模式等重构完再放出来 */}
                {/* <GlobalSearch */}
                {/*  handleModeChange={this.handleModeChangeV2} */}
                {/*  isOldCompany={isOldCompany} */}
                {/*  adminMode={adminMode} */}
                {/*  tenantMode={tenantMode} */}
                {/*  languageCode={language.code} */}
                {/* /> */}
                {/* task 17069 */}
                {adminMode && tenantMode && (
                  <div
                    className="operating-instruction"
                    onClick={() => this.setState({ operatingVisible: true })}
                  >
                    <Tooltip
                      placement="bottom"
                      title={messages("dashboard.key173") /* 设置指南 */}
                    >
                      <Icon type="compass" />
                    </Tooltip>
                  </div>
                )}
                {!user.enableNewPermission && !adminMode && (
                  <Divider type="vertical" />
                )}
                <CommonFunc menuRouterDeal={this.menuRouterDeal} />
                {/* <div
                className="doc-button"
                onClick={() => this.menuRouterDeal(menuRoute.getMenuItemByAttr("doc", 'key').url)}
              >
                <SVGIcon type="read" className='font-default' style={{fontSize: '14px'}}/>
                <span className="title">{messages('dashboard.key136')/*帮助*!/</span>
              </div>
              <Divider type="vertical"/> */}

                {this.renderModeBtn()}
                <UserInfo
                  loginUser={loginUser}
                  menuRouterDeal={this.menuRouterDeal}
                />
              </div>
              {this.renderBreadcrumb()}
            </Header>
            <Content
              className={`helios-content ${
                collapsed ? "collapsed" : "not-collapsed"
              }`}
            >
              {check ? (
                error ? (
                  <Error {...errorContent} />
                ) : (
                  this.mainRoute
                )
              ) : (
                <Loading />
              )}
            </Content>
          </div>
          {/* 停机公告 */}
          {/* <StopAnnonuce/> */}
          {/* 新用户进入提示协议 */}
          {<NewProtocolModal resetPassword={user.resetPassword} />}
          {/* 欢迎消息模态框 */}
          {!user.resetPassword && <WelcomeMessagesModal />}
          {/* 操作指南模态框 */}
          {/* task 17069 */}
          {adminMode && tenantMode && (
            <OperatingInstuction
              show={operatingVisible}
              closeModal={this.closeOperatingInstuction}
            />
          )}
        </div>
      </RequireETraining>
    );
  }
}

Main.contextTypes = {
  router: React.PropTypes.object,
};

function mapStateToProps(state) {
  return {
    languageList: state.login.languageList,
    tenantMode: state.main.tenantMode, // 集团模式
    adminMode: state.main.adminMode, // 管理员模式
    language: state.main.language,
    currentPage: state.main.currentPage, // 路由堆栈（面包屑导航）
    user: state.login.user,
    company: state.login.company,
    userPermission: state.login.userPermission,
    userPermissionAllMenus: state.login.userPermissionAllMenus,
    newPermissionSortedMenus: state.login.newPermissionSortedMenus,
    loginUser: state.login.loginUser,
    profile: state.login.profile,
    tenant: state.login.tenant,
    organization: state.budget.organization,
    userOrganization: state.login.organization,
    billingType: state.billing.billingType,
    searchBilling: state.billing.searchBilling,
    isOldCompany: state.login.isOldCompany,
    authToken: state.main.authToken,
    publicToken: state.main.publicToken,
    standardRulesGroup: state.setting.standardRulesGroup,
    expenseTypeRules: state.setting.expenseTypeRules,
    creditModel: state.creditSetting.creditModel,
  };
}

export default connect(mapStateToProps)(Main);
